# -*- coding: utf-8 -*-
from pickletools import long1
import sys
import json
import uuid
import oss2
import base64
import requests
from pyDes import des, CBC, PAD_PKCS5
from datetime import datetime, timedelta, timezone
from urllib.parse import urlparse
from urllib3.exceptions import InsecureRequestWarning
from urllib.parse import quote
import time
import urllib.parse
from Crypto.Cipher import AES
import hashlib
#import database_mysql as db
import smtplib
from email.mime.text import MIMEText
from email.header import Header
    


# debug模式

debug = False
if debug:
    requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

# 获取当前utc时间，并格式化为北京时间
def getTimeStr():
    utc_dt = datetime.utcnow().replace(tzinfo=timezone.utc)
    bj_dt = utc_dt.astimezone(timezone(timedelta(hours=8)))
    return bj_dt.strftime("%Y-%m-%d %H:%M:%S")


# 输出调试信息，并及时刷新缓冲区
def log(content):
    print(getTimeStr() + ' ' + str(content))
    sys.stdout.flush()


def getSession(username,password,user):
    try:
        session = getSession_index(username,password)
        return session
    except Exception as e :
        log("登录失败，可能是账号密码错误，请检查后再提交")
        log("错误：" ,str(e))
        InfoSubmit(user['weixinID'],"登录失败，可能是账号密码错误，请检查后再提交\r\n" + "错误日志：" + str(e))


    
def getSession_index(username,password):
    session=requests.session()
    headers={
        'Host': 'xxmu.campusphere.net',
        'Connection': 'keep-alive',
        'Upgrade-Insecure-Requests': '1',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36 Edg/89.0.774.57',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
        'Sec-Fetch-Site': 'none',
        'Sec-Fetch-Mode': 'navigate',
        'Sec-Fetch-User': '?1',
        'Sec-Fetch-Dest': 'document',
        'Accept-Encoding': 'gzip, deflate, br',
        'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6'
    }
    session.headers=headers
    url_login='https://xxmu.campusphere.net/iap/login?service=https%3A%2F%2Fxxmu.campusphere.net%2Fportal%2Flogin'
    res = session.get(url_login,allow_redirects=False)
    url = res.headers['location']
    result = urllib.parse.urlparse(url)
    dict1 = urllib.parse.parse_qs(result.query)
    #it的params是第二次重定向url的'_2lBepC'值
    params = dict1['_2lBepC'][0]
    it1=params
    #申请it，记得更换headers，否则申请到的it值不能用
    data ="lt={}".format(params)
    session.headers['Accept'] = 'application/json, text/plain, */*'
    session.headers['X-Requested-With'] = 'XMLHttpRequest'
    session.headers['Content-Type'] = 'application/x-www-form-urlencoded'
    session.headers['Origin'] = 'https://xxmu.campusphere.net'
    session.headers['Referer'] = '{}'.format(url)
    url_It='https://xxmu.campusphere.net/iap/security/lt'
    res=session.post(url=url_It,data=data)
    it = res.json()['result']['_lt']
    if it != it1:
        print('it值不符合')
        exit()
    data = {
        'username':username,
        'password':password,
        'mobile':'',
        'dllt':'cpdaily',
        'captcha':'',
        'rememberMe':'false',
        'lt':'{}'.format(it)
    }
    url_doLogin = 'https://xxmu.campusphere.net/iap/doLogin'
    res = session.post(url=url_doLogin,data=data,allow_redirects=False)
    #print(res.json())
    url = res.json()['url']
    res = session.get(url=url,allow_redirects=False)
    cookies = requests.utils.dict_from_cookiejar(res.cookies)
    session=requests.session()
    session.cookies = requests.utils.cookiejar_from_dict(cookies, cookiejar=None, overwrite=True)
    print('cookies',cookies)
#    session.cookies = cookielib.LWPCookieJar(filename="cookies.txt")
#    session.cookies.save()
    return session

# 获取未填写的信息收集
def getUnSignedTasks(session,user):
    headers = {
        'User-Agent': 'Mozilla/5.0 (iPad; CPU OS 15_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148(4530145792)cpdaily/9.0.18 wisedu/9.0.18',
        'Content-Type': 'application/json',
    }
    data = {"pageNumber":1,"pageSize":20}
    url = 'https://xxmu.campusphere.net/wec-counselor-collector-apps/stu/collector/queryCollectorProcessingList'
    res = session.post(url=url,headers=headers,data=json.dumps(data))
#    print(res.json())
    if len(res.json()['datas']['rows']) < 1:
        log('当前没有未填写的信息收集')
        InfoSubmit(user['weichatID'],"自动提交失败，当前没有未填写的信息收集！")
    # log(res.json())
    latestTask = res.json()['datas']['rows'][0]
    return {
        'formWid': latestTask['formWid'],
        'collectWid': latestTask['wid'],
        'instanceWid':latestTask['instanceWid'],
        "subject":latestTask['subject'],
        'senderUserName':latestTask['senderUserName']
    }
#    return {
#        'formWid': '19968',
#        'collectWid': '20516'
#    }
    
#获取历史信息收集任务
def gethistorycollecttask(session):
    url = 'https://xxmu.campusphere.net/wec-counselor-collector-apps/stu/collector/queryCollectorHistoryList'
    headers = {
        'User-Agent': 'Mozilla/5.0 (iPad; CPU OS 15_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148(4530145792)cpdaily/9.0.18 wisedu/9.0.18',
        'Content-Type': 'application/json',
    }
    data = '{"pageNumber":1,"pageSize":20}'
    res = session.post(url=url,headers=headers,data=data)
    if len(res.json()["datas"]["rows"])<1:
        log('当前未获取到历史任务信息')
        return {
            'formWid':"",
            'collectWid':"" ,
            'instanceWid':"",
            "subject":"",
            'senderUserName':""
        }
    else:
        latestTask = res.json()['datas']['rows'][0]
        return {
            'formWid': latestTask['formWid'],
            'collectWid': latestTask['wid'],
            'instanceWid':latestTask['instanceWid'],
            "subject":latestTask['subject'],
            'senderUserName':latestTask['senderUserName']
        }

# 获取信息收集任务详情
def getDetailTask(session, params):
    headers = {
        'User-Agent': 'Mozilla/5.0 (iPad; CPU OS 15_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148(4530145792)cpdaily/9.0.18 wisedu/9.0.18',
        'Content-Type': 'application/json',
    }
    formWid = params['formWid']
    collectWid = params['collectWid']
    instanceWid = params['instanceWid']
    #获取schoolTaskWid
    res = session.post(url='https://xxmu.campusphere.net/wec-counselor-collector-apps/stu/collector/detailCollector',headers=headers, data=json.dumps({"collectorWid":collectWid,"instanceWid":instanceWid}))
#    print(res.json())
    schoolTaskWid = res.json()['datas']['collector']['schoolTaskWid']    
    getFormFields = 'https://xxmu.campusphere.net/wec-counselor-collector-apps/stu/collector/getFormFields'
    res = session.post(url=getFormFields, headers=headers, data=json.dumps(
        {"pageSize": 100, "pageNumber": 1, "formWid": formWid, "collectorWid": collectWid}))
    form = res.json()['datas']['rows']
#    for k,v in {'collectWid': collectWid, 'formWid': formWid, 'schoolTaskWid': schoolTaskWid, 'form': form}.items():
#        print(k,v)
#    print({'collectWid': collectWid, 'formWid': formWid, 'schoolTaskWid': schoolTaskWid, 'form': form})
    return {'collectWid': collectWid, 'formWid': formWid, 'schoolTaskWid': schoolTaskWid, 'form': form,'instanceWid':instanceWid}


#从历史表单中提取提交信息
def get_form_data_history(session,params_history):
    formWid = params_history['formWid']
    collectorWid = params_history['collectWid']
    instanceWid = params_history['instanceWid']
    data =  {
        "pageNumber":"1",
        "pageSize":"20",
        "formWid":formWid,
        "collectorWid":collectorWid,
        "instanceWid":instanceWid}
    print(data)
    url = 'https://xxmu.campusphere.net/wec-counselor-collector-apps/stu/collector/getFormFields'
    headers = {
        'User-Agent': 'Mozilla/5.0 (iPad; CPU OS 15_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148(4530145792)cpdaily/9.0.18 wisedu/9.0.18',
        'Content-Type': 'application/json',
    }
    res = session.post(url=url,headers=headers,data=json.dumps(data))
    datas = res.json()["datas"]["rows"]
    form_data_history=[]
    for data in datas:
        if data['fieldType'] == '2':
#            print(data['title'])
#            print(data['fieldType'])
            for fieldItem in data['fieldItems']:
                #print(fieldItem)
                if fieldItem['isSelected'] == 1:
#                    print(fieldItem['content'])
                    form_data_history.append({
                        'title':data['title'],
                        'fieldType':data['fieldType'],
                        'content':fieldItem['content']
                    })
        elif data['fieldType'] == '1':
#            print(data['title'])
#            print(data['fieldType'])
#            print(data['value'])
            form_data_history.append({
                'title':data['title'],
                'fieldType':data['fieldType'],
                'value':data['value']
            })
    return form_data_history


# 填写form
def fillForm(task,form_data_history):
    sort = 1
    form=task['form']
    for formItem in form[:]:
        # 只处理必填项
        if formItem['isRequired'] :
            default = form_data_history[sort - 1]
            #print(default)
            if formItem['title'] != default['title']:
                log('第%d个默认配置不正确，请检查' % sort)
                exit(-1)
            # 文本直接赋值
            if formItem['fieldType'] == '1' or formItem['fieldType'] == '5':
                formItem['value'] = default['value']
            # 单选框需要删掉多余的选项
            if formItem['fieldType'] == '2':
            #    print(default)
                # 填充默认值
                formItem['value'] = default['content']
                fieldItems = formItem['fieldItems']
                for i in range(0, len(fieldItems))[::-1]:
                    if fieldItems[i]['content'] != default['content']:
                        del fieldItems[i]
            # 多选需要分割默认选项值，并且删掉无用的其他选项
            log('必填问题%d：' % sort + formItem['title'])
            log('答案%d：' % sort + formItem['value'])
            sort += 1
        else:
            form.remove(formItem)
    # print(form)
    return form

# 上传图片到阿里云oss
def uploadPicture(session, image):
    url = 'https://xxmu.campusphere.net/wec-counselor-sign-apps/stu/oss/getUploadPolicy'
    res = session.post(url=url, headers={'content-type': 'application/json'}, data=json.dumps({'fileType':1}), verify=False)
    datas = res.json().get('datas')
#    print(res.text)
    fileName = datas.get('fileName')
    policy= datas.get('policy')
    accessKeyId = datas.get('accessid')
    signature = datas.get('signature')
    policyHost=datas.get('host')
    f = {"file": (image, open(image, "rb"), "image/jpg")}
    data = {
        'key': fileName,
        'policy': policy,
        'OSSAccessKeyId': accessKeyId,
        'success_action_status': 200,
        'signature': signature
    }
    res = session.post(url=policyHost,headers={'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:50.0) Gecko/20100101 Firefox/50.0'},
                      data=data,files=f,verify=False)
#    print(res.text)
    return fileName


# 获取图片上传位置
def getPictureUrl(session, fileName):
    url = 'https://xxmu.campusphere.net/wec-counselor-sign-apps/stu/sign/previewAttachment'
    data = {
        'ossKey': fileName
    }
    res = session.post(url=url, headers={'content-type': 'application/json'}, data=json.dumps(data), verify=False)
    photoUrl = res.json().get('datas')
    print(photoUrl)
    return photoUrl

# DES加密
def DESEncrypt(s, key='b3L26XNL'):
    key = key
    iv = b"\x01\x02\x03\x04\x05\x06\x07\x08"
    k = des(key, CBC, iv, pad=None, padmode=PAD_PKCS5)
    encrypt_str = k.encrypt(s)
    return base64.b64encode(encrypt_str).decode()

#AES加密
def encryptAES(data, key):
    ivStr = '\x01\x02\x03\x04\x05\x06\x07\x08\x09\x01\x02\x03\x04\x05\x06\x07'
    aes = AES.new(bytes(key, encoding='utf-8'), AES.MODE_CBC,bytes(ivStr, encoding="utf8"))
    text_length = len(data)
    amount_to_pad = AES.block_size - (text_length % AES.block_size)
    if amount_to_pad == 0:
        amount_to_pad = AES.block_size
    pad = chr(amount_to_pad)
    data = data + pad * amount_to_pad
    text = aes.encrypt(bytes(data, encoding='utf-8'))
    text = base64.encodebytes(text)
    text = text.decode('utf-8').strip()
    return text

#MD5加密
def encryptmd5(str):
    md5 = hashlib.md5()
    md5.update(str.encode("utf8"))
    return md5.hexdigest()



# 提交签到任务
def submitForm(task,session,form,user):
#    user = user['user']
    # Cpdaily-Extension
    extension = {
        "lon": user['lon'],
        "model": "MI 6",
        "appVersion": "9.0.14",
        "systemVersion": "8.0.0",
        "userId": user['username'],
        "systemName": "android",
        "lat": user['lat'],
        "deviceId": str(uuid.uuid1())
    }
    headers = {
        # 'tenantId': '1019318364515869',
        'User-Agent': 'Mozilla/5.0 (Linux; Android 8.0.0; MI 6 Build/OPR1.170623.027; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/92.0.4515.131 Mobile Safari/537.36 okhttp/3.12.4 cpdaily/9.0.14 wisedu/9.0.14',
        'CpdailyStandAlone': '0',
        'extension': '1',
        'Cpdaily-Extension': DESEncrypt(json.dumps(extension)),
        'Content-Type': 'application/json; charset=utf-8',
        'Accept-Encoding': 'gzip',
        # 'Host': 'swu.cpdaily.com',
        'Connection': 'Keep-Alive',}
    params = {
        "formWid":task['formWid'],
        "address": user['address'],
        "collectWid": task['collectWid'],
        "instanceWid":task['instanceWid'],
        "schoolTaskWid": task['schoolTaskWid'],
        "form": form,
        "uaIsCpadaily":True,
        "latitude": user['lat'],
        'longitude': user['lon']
    }
    bodyString = encryptAES(json.dumps(params), 'SASEoK4Pa5d4SssO')
    formData = {
        'version':'first_v3',
        'calVersion':'firstv',
        'bodyString': bodyString,
        'sign': encryptmd5(urllib.parse.urlencode(params) + "&SASEoK4Pa5d4SssO")
    }
    formData.update(extension)
    res = session.post(url='https://xxmu.campusphere.net/wec-counselor-collector-apps/stu/collector/submitForm',
                       headers=headers, data=json.dumps(formData), verify=not debug)
    message = res.json()['message']    
    if message == 'SUCCESS':
        log('信息收集自动提交成功！')
        InfoSubmit(user['weichatID'],'信息收集自动提交成功！')
    else:
        log('信息收集自动提交失败，原因是：' + message)
        InfoSubmit(user['weichatID'],'信息收集自动提交失败，原因是：' + str(message))


# 综合提交
def InfoSubmit(weichatID,msg):
    #sendwechat_private(weichatID,msg)
    print("推送关闭")
    #sendemail(weichatID,msg,"今日校园结果推送")
    pushdeer(weichatID,msg)

def pushdeer(weichatID,msg):
    res=requests.post("http://lingran.cc:8800/message/push?pushkey={}&text={}".format(weichatID,msg))
    print(res.json()["content"]["result"])

    
def sendemail(receiver,mail_msg,subject):
    #发送邮件服务器地址
    smtp_server = 'smtp.yeah.net'
    #发送方账号
    sender = 'senquana@yeah.net'
    #发送方密码（或授权密码）
    password = 'IPPYTTQTKTIHDACD'
    #邮件标题
    #subject = 'Python SMTP'
    #邮件内容
    #三个参数：第一个为文本内容，第二个 plain 设置文本格式，html 设置文本格式为html格式  第三个 utf-8 设置编码
    message = MIMEText(mail_msg, 'plain', 'utf-8')  # 发送内容 （文本内容，发送格式，编码格式）
    #发送地址
    message['From'] = sender
    #接受地址
    message['To'] = receiver
    #邮件标题
    message['Subject'] = Header(subject,'utf-8')
    try:
        # 创建SMTP对象
        smtp = smtplib.SMTP()
        # 连接服务器
        smtp.connect(smtp_server)
        # 登录邮箱账号
        smtp.login(sender, password)
        # 发送账号信息
        smtp.sendmail(sender, receiver, message.as_string())
        print('success:发送成功')
    except smtplib.SMTPException:
        print('error:邮件发送失败')
    finally:
         # 关闭
        smtp.quit()


#微信推送
def sendwechat_private(weixinID,msg):
    url = "http://w.senquan.top:5699"
    payload = json.dumps({
        "token": "yuanchenglianjie",
        "api": "SendTextMsg",
        "robot_wxid": "wxid_ih93rglfecj722",
        "to_wxid": "{}".format(weixinID),
        "msg": "{}".format(msg)
    })
    headers = {
        'Content-Type': 'application/json'
    }
    res = requests.post(url, headers=headers, data=payload)
    status = res.json()['Code']
    return status

def main(user):
    username=user['username']
    password = user['password']
    log(username)
    session = getSession(username,password,user)
    #获取完成的信息收集的任务
    params = getUnSignedTasks(session,user)
    #获取详细的未完成的信息收集任务
    task = getDetailTask(session, params)
    #获取历史完成的信息收集任务
    params_history = gethistorycollecttask(session)
    #获取详细的历史完成的信息收集任务
#    task_history = getDetailTask(session, params_history)
    #从历史任务中提取信息收集表单
    form_data_history = get_form_data_history(session,params_history)
    form = fillForm(task,form_data_history)
    submitForm(task,session, form,user)


### username,password,lat,lot,weixinID

def handler(event, context):
    user={
        'username':"username",
        'password':"passwd",
        'address':"xxxxxx",
        'lon':"xxxx",
        'lat':"xxxx",
        'weichatID':"xxxx",
        'status':10
        }
    main(user)
    return "success"


